// (C) 2022 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other 
// software and tools, and its AMPP partner logic functions, and any output 
// files from any of the foregoing (including device programming or simulation 
// files), and any associated documentation or information are expressly subject 
// to the terms and conditions of the Intel Program License Subscription 
// Agreement, Intel FPGA IP License Agreement, or other applicable 
// license agreement, including, without limitation, that your use is for the 
// sole purpose of programming logic devices manufactured by Intel and sold by 
// Intel or its authorized distributors.  Please refer to the applicable 
// agreement for further details.

module CRC16_D8
  (
    Data,
    Crc,
    
    NewCrc
  );

  input   [ 7: 0] Data;                     //New byte value
  input   [15: 0] Crc;                      //Current CRC value
  
  output  [15: 0] NewCrc;                   //New CRC value
  
  //Internal Wires
  wire    [ 7: 0] d;                        //Data value with short name
  wire    [15: 0] c;                        //CRC value with short name
  wire    [15: 0] NewCrc;                   //New CRC value

  // polynomial: (0 1 3 4 6 8 10 12 13 14 16)
  // data width: 8
  // convention: the first serial bit is D[7]
  
  assign d = Data;
  assign c = Crc;

  assign NewCrc[ 0] = d[7] ^ d[6] ^ d[3] ^ d[2] ^ d[0] ^ c[8] ^ c[10] ^ c[11] ^ c[14] ^ c[15];
  assign NewCrc[ 1] = d[6] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[8] ^ c[9] ^ c[10] ^ c[12] ^ c[14];
  assign NewCrc[ 2] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[9] ^ c[10] ^ c[11] ^ c[13] ^ c[15];
  assign NewCrc[ 3] = d[7] ^ d[4] ^ d[0] ^ c[8] ^ c[12] ^ c[15];
  assign NewCrc[ 4] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[13] ^ c[14] ^ c[15];
  assign NewCrc[ 5] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ c[9] ^ c[10] ^ c[11] ^ c[12] ^ c[14] ^ c[15];
  assign NewCrc[ 6] = d[6] ^ d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[12] ^ c[13] ^ c[14];
  assign NewCrc[ 7] = d[7] ^ d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[13] ^ c[14] ^ c[15];
  assign NewCrc[ 8] = d[3] ^ d[0] ^ c[0] ^ c[8] ^ c[11];
  assign NewCrc[ 9] = d[4] ^ d[1] ^ c[1] ^ c[9] ^ c[12];
  assign NewCrc[10] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[0] ^ c[2] ^ c[8] ^ c[11] ^ c[13] ^ c[14] ^ c[15];
  assign NewCrc[11] = d[7] ^ d[6] ^ d[4] ^ d[1] ^ c[3] ^ c[9] ^ c[12] ^ c[14] ^ c[15];
  assign NewCrc[12] = d[6] ^ d[5] ^ d[3] ^ d[0] ^ c[4] ^ c[8] ^ c[11] ^ c[13] ^ c[14];
  assign NewCrc[13] = d[4] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[5] ^ c[8] ^ c[9] ^ c[10] ^ c[11] ^ c[12];
  assign NewCrc[14] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[1] ^ d[0] ^ c[6] ^ c[8] ^ c[9] ^ c[12] ^ c[13] ^ c[14] ^ c[15];
  assign NewCrc[15] = d[7] ^ d[6] ^ d[5] ^ d[2] ^ d[1] ^ c[7] ^ c[9] ^ c[10] ^ c[13] ^ c[14] ^ c[15];
  
endmodule
